﻿#region License
// (c) Garry McGlennon 2009
// 
// This project is made available under the Microsoft Public License (Ms-PL)
// Code is provided as is and with no warrenty – Use at your own risk
// 
// View the project and the latest code at http://dnpframework.codeplex.com/
// 
// All other rights reserved.
// 
// blog: www.dotNetProfessional.com/blog/
#endregion
using System;
using System.Xml;
using dnp.Framework.Database.DatabaseExplorer;
using MbUnit.Framework;

namespace dnp.Framework.UnitTest.Database.DatabaseExplorer
{
    [TestFixture]
    public class ViewColumnTest
    {
        private Framework.Database.DatabaseExplorer.Database _database;

        [TestFixtureSetUp]
        public void Setup()
        {
            _database = new Framework.Database.DatabaseExplorer.Database("ReferenceSchema", null);
        }

        [Test]
        public void Name()
        {
            View v = _database.Views["dbo.v_AllDataTypes"];
            ViewColumn c;

            c = v.Columns["BigInt"];
            Assert.AreEqual("BigInt", c.Name);

            c = v.Columns["Binary"];
            Assert.AreEqual("Binary", c.Name);

            c = v.Columns["Bit"];
            Assert.AreEqual("Bit", c.Name);

            c = v.Columns["Char"];
            Assert.AreEqual("Char", c.Name);

            c = v.Columns["DateTime"];
            Assert.AreEqual("DateTime", c.Name);

            c = v.Columns["Decimal"];
            Assert.AreEqual("Decimal", c.Name);

            c = v.Columns["Int"];
            Assert.AreEqual("Int", c.Name);

            c = v.Columns["Money"];
            Assert.AreEqual("Money", c.Name);

            c = v.Columns["Nchar"];
            Assert.AreEqual("Nchar", c.Name);

            c = v.Columns["Ntext"];
            Assert.AreEqual("Ntext", c.Name);

            c = v.Columns["Numeric"];
            Assert.AreEqual("Numeric", c.Name);

            c = v.Columns["Nvarchar"];
            Assert.AreEqual("Nvarchar", c.Name);

            c = v.Columns["NVarcharMax"];
            Assert.AreEqual("NVarcharMax", c.Name);

            c = v.Columns["Real"];
            Assert.AreEqual("Real", c.Name);

            c = v.Columns["SmallDateTime"];
            Assert.AreEqual("SmallDateTime", c.Name);

            c = v.Columns["SmallInt"];
            Assert.AreEqual("SmallInt", c.Name);

            c = v.Columns["SmallMoney"];
            Assert.AreEqual("SmallMoney", c.Name);

            c = v.Columns["SqlVariant"];
            Assert.AreEqual("SqlVariant", c.Name);

            c = v.Columns["Text"];
            Assert.AreEqual("Text", c.Name);

            c = v.Columns["Timestamp"];
            Assert.AreEqual("Timestamp", c.Name);

            c = v.Columns["TinyInt"];
            Assert.AreEqual("TinyInt", c.Name);

            c = v.Columns["UniqueIdentifier"];
            Assert.AreEqual("UniqueIdentifier", c.Name);

            c = v.Columns["VarBinary"];
            Assert.AreEqual("VarBinary", c.Name);

            c = v.Columns["VarBinaryMax"];
            Assert.AreEqual("VarBinaryMax", c.Name);

            c = v.Columns["VarChar"];
            Assert.AreEqual("VarChar", c.Name);

            c = v.Columns["VarCharMax"];
            Assert.AreEqual("VarCharMax", c.Name);

            c = v.Columns["Xml"];
            Assert.AreEqual("Xml", c.Name);
        }

        [Test]
        public void Alias()
        {
            View v = _database.Views["dbo.v_AllDataTypes"];

            // Check that aliased fields have thier alias
            Assert.AreEqual("VarCharMax", v.Columns["VarCharMax"].Alias);
        }

        [Test]
        public void Description()
        {
            // Check that descriptions are correct. (not supported for Views so just empty string)
            View v = _database.Views["dbo.v_AllDataTypes"];

            // Check that aliased fields have thier alias
            Assert.AreEqual("", v.Columns["VarCharMax"].Description);
        }
        [Test]
        public void CharacterMaximumLength()
        {
            View v = _database.Views["dbo.v_AllDataTypes"];
            ViewColumn c;

            c = v.Columns["BigInt"];
            Assert.AreEqual(null, c.CharacterMaximumLength);

            c = v.Columns["Binary"];
            Assert.AreEqual(50, c.CharacterMaximumLength);

            c = v.Columns["Bit"];
            Assert.AreEqual(null, c.CharacterMaximumLength);

            c = v.Columns["Char"];
            Assert.AreEqual(10, c.CharacterMaximumLength);

            c = v.Columns["DateTime"];
            Assert.AreEqual(null, c.CharacterMaximumLength);

            c = v.Columns["Decimal"];
            Assert.AreEqual(null, c.CharacterMaximumLength);

            c = v.Columns["Int"];
            Assert.AreEqual(null, c.CharacterMaximumLength);

            c = v.Columns["Money"];
            Assert.AreEqual(null, c.CharacterMaximumLength);

            c = v.Columns["Nchar"];
            Assert.AreEqual(10, c.CharacterMaximumLength);

            c = v.Columns["Ntext"];
            Assert.AreEqual(1073741823, c.CharacterMaximumLength);

            c = v.Columns["Numeric"];
            Assert.AreEqual(null, c.CharacterMaximumLength);

            c = v.Columns["Nvarchar"];
            Assert.AreEqual(50, c.CharacterMaximumLength);

            c = v.Columns["NVarcharMax"];
            Assert.AreEqual(-1, c.CharacterMaximumLength);

            c = v.Columns["Real"];
            Assert.AreEqual(null, c.CharacterMaximumLength);

            c = v.Columns["SmallDateTime"];
            Assert.AreEqual(null, c.CharacterMaximumLength);

            c = v.Columns["SmallInt"];
            Assert.AreEqual(null, c.CharacterMaximumLength);

            c = v.Columns["SmallMoney"];
            Assert.AreEqual(null, c.CharacterMaximumLength);

            c = v.Columns["SqlVariant"];
            Assert.AreEqual(0, c.CharacterMaximumLength);

            c = v.Columns["Text"];
            Assert.AreEqual(2147483647, c.CharacterMaximumLength);

            c = v.Columns["Timestamp"];
            Assert.AreEqual(null, c.CharacterMaximumLength);

            c = v.Columns["TinyInt"];
            Assert.AreEqual(null, c.CharacterMaximumLength);

            c = v.Columns["UniqueIdentifier"];
            Assert.AreEqual(null, c.CharacterMaximumLength);

            c = v.Columns["VarBinary"];
            Assert.AreEqual(50, c.CharacterMaximumLength);

            c = v.Columns["VarBinaryMax"];
            Assert.AreEqual(-1, c.CharacterMaximumLength);

            c = v.Columns["VarChar"];
            Assert.AreEqual(50, c.CharacterMaximumLength);

            c = v.Columns["VarCharMax"];
            Assert.AreEqual(-1, c.CharacterMaximumLength);

            c = v.Columns["Xml"];
            Assert.AreEqual(-1, c.CharacterMaximumLength);
        }

        [Test]
        public void CollationName()
        {
            View v = _database.Views["dbo.v_AllDataTypes"];

            // Check that aliased fields have thier alias
            Assert.AreEqual("SQL_Latin1_General_CP1_CI_AS", v.Columns["VarChar"].CollationName);
        }

        [Test]
        public void ColumnDefault()
        {
            View v = _database.Views["dbo.v_AllDataTypes"];
            ViewColumn c;

            c = v.Columns["BigInt"];
            Assert.AreEqual(string.Empty, c.ColumnDefault);

            c = v.Columns["Binary"];
            Assert.AreEqual(string.Empty, c.ColumnDefault);

            c = v.Columns["Bit"];
            Assert.AreEqual(string.Empty, c.ColumnDefault);

            c = v.Columns["Char"];
            Assert.AreEqual(string.Empty, c.ColumnDefault);

            c = v.Columns["DateTime"];
            Assert.AreEqual(string.Empty, c.ColumnDefault);

            c = v.Columns["Decimal"];
            Assert.AreEqual(string.Empty, c.ColumnDefault);

            c = v.Columns["Int"];
            Assert.AreEqual(string.Empty, c.ColumnDefault);

            c = v.Columns["Money"];
            Assert.AreEqual(string.Empty, c.ColumnDefault);

            c = v.Columns["Nchar"];
            Assert.AreEqual(string.Empty, c.ColumnDefault);

            c = v.Columns["Ntext"];
            Assert.AreEqual(string.Empty, c.ColumnDefault);

            c = v.Columns["Numeric"];
            Assert.AreEqual(string.Empty, c.ColumnDefault);

            c = v.Columns["Nvarchar"];
            Assert.AreEqual(string.Empty, c.ColumnDefault);

            c = v.Columns["NVarcharMax"];
            Assert.AreEqual(string.Empty, c.ColumnDefault);

            c = v.Columns["Real"];
            Assert.AreEqual(string.Empty, c.ColumnDefault);

            c = v.Columns["SmallDateTime"];
            Assert.AreEqual(string.Empty, c.ColumnDefault);

            c = v.Columns["SmallInt"];
            Assert.AreEqual(string.Empty, c.ColumnDefault);

            c = v.Columns["SmallMoney"];
            Assert.AreEqual(string.Empty, c.ColumnDefault);

            c = v.Columns["SqlVariant"];
            Assert.AreEqual(string.Empty, c.ColumnDefault);

            c = v.Columns["Text"];
            Assert.AreEqual(string.Empty, c.ColumnDefault);

            c = v.Columns["Timestamp"];
            Assert.AreEqual(string.Empty, c.ColumnDefault);

            c = v.Columns["TinyInt"];
            Assert.AreEqual(string.Empty, c.ColumnDefault);

            c = v.Columns["UniqueIdentifier"];
            Assert.AreEqual(string.Empty, c.ColumnDefault);

            c = v.Columns["VarBinary"];
            Assert.AreEqual(string.Empty, c.ColumnDefault);

            c = v.Columns["VarBinaryMax"];
            Assert.AreEqual(string.Empty, c.ColumnDefault);

            c = v.Columns["VarChar"];
            Assert.AreEqual(string.Empty, c.ColumnDefault);

            c = v.Columns["VarCharMax"];
            Assert.AreEqual(string.Empty, c.ColumnDefault);

            c = v.Columns["Xml"];
            Assert.AreEqual(string.Empty, c.ColumnDefault);
        }

        [Test]
        public void DataType_AllDataTypes()
        {
            View v = _database.Views["dbo.v_AllDataTypes"];
            ViewColumn c;

            c = v.Columns["BigInt"];
            Assert.AreEqual("bigint", c.DataType);

            c = v.Columns["Binary"];
            Assert.AreEqual("binary", c.DataType);

            c = v.Columns["Bit"];
            Assert.AreEqual("bit", c.DataType);

            c = v.Columns["Char"];
            Assert.AreEqual("char", c.DataType);

            c = v.Columns["DateTime"];
            Assert.AreEqual("datetime", c.DataType);

            c = v.Columns["Decimal"];
            Assert.AreEqual("decimal", c.DataType);

            c = v.Columns["Int"];
            Assert.AreEqual("int", c.DataType);

            c = v.Columns["Money"];
            Assert.AreEqual("money", c.DataType);

            c = v.Columns["Nchar"];
            Assert.AreEqual("nchar", c.DataType);

            c = v.Columns["Ntext"];
            Assert.AreEqual("ntext", c.DataType);

            c = v.Columns["Numeric"];
            Assert.AreEqual("numeric", c.DataType);

            c = v.Columns["Nvarchar"];
            Assert.AreEqual("nvarchar", c.DataType);

            c = v.Columns["NVarcharMax"];
            Assert.AreEqual("nvarchar", c.DataType);

            c = v.Columns["Real"];
            Assert.AreEqual("real", c.DataType);

            c = v.Columns["SmallDateTime"];
            Assert.AreEqual("smalldatetime", c.DataType);

            c = v.Columns["SmallInt"];
            Assert.AreEqual("smallint", c.DataType);

            c = v.Columns["SmallMoney"];
            Assert.AreEqual("smallmoney", c.DataType);

            c = v.Columns["SqlVariant"];
            Assert.AreEqual("sql_variant", c.DataType);

            c = v.Columns["Text"];
            Assert.AreEqual("text", c.DataType);

            c = v.Columns["Timestamp"];
            Assert.AreEqual("timestamp", c.DataType);

            c = v.Columns["TinyInt"];
            Assert.AreEqual("tinyint", c.DataType);

            c = v.Columns["UniqueIdentifier"];
            Assert.AreEqual("uniqueidentifier", c.DataType);

            c = v.Columns["VarBinary"];
            Assert.AreEqual("varbinary", c.DataType);

            c = v.Columns["VarBinaryMax"];
            Assert.AreEqual("varbinary", c.DataType);

            c = v.Columns["VarChar"];
            Assert.AreEqual("varchar", c.DataType);

            c = v.Columns["VarCharMax"];
            Assert.AreEqual("varchar", c.DataType);

            c = v.Columns["Xml"];
            Assert.AreEqual("xml", c.DataType);
        }

        [Test]
        public void DateTimePrecision()
        {
            View v = _database.Views["dbo.v_AllDataTypes"];
            ViewColumn c;

            c = v.Columns["DateTime"];
            Assert.AreEqual(3, c.DateTimePrecision);

            c = v.Columns["SmallDateTime"];
            Assert.AreEqual(0, c.DateTimePrecision);
        }

        [Test]
        public void DotNetType()
        {
            View v = _database.Views["dbo.v_AllDataTypes"];
            ViewColumn c;

            c = v.Columns["BigInt"];
            Assert.AreEqual(typeof(Int64), c.DotNetType);

            c = v.Columns["Binary"];
            Assert.AreEqual(typeof(byte[]), c.DotNetType);

            c = v.Columns["Bit"];
            Assert.AreEqual(typeof(Boolean), c.DotNetType);

            c = v.Columns["Char"];
            Assert.AreEqual(typeof(string), c.DotNetType);

            c = v.Columns["DateTime"];
            Assert.AreEqual(typeof(DateTime), c.DotNetType);

            c = v.Columns["Decimal"];
            Assert.AreEqual(typeof(Decimal), c.DotNetType);

            c = v.Columns["Int"];
            Assert.AreEqual(typeof(Int32), c.DotNetType);

            c = v.Columns["Money"];
            Assert.AreEqual(typeof(Decimal), c.DotNetType);

            c = v.Columns["Nchar"];
            Assert.AreEqual(typeof(string), c.DotNetType);

            c = v.Columns["Ntext"];
            Assert.AreEqual(typeof(string), c.DotNetType);

            c = v.Columns["Numeric"];
            Assert.AreEqual(typeof(Decimal), c.DotNetType);

            c = v.Columns["Nvarchar"];
            Assert.AreEqual(typeof(string), c.DotNetType);

            c = v.Columns["NVarcharMax"];
            Assert.AreEqual(typeof(string), c.DotNetType);

            c = v.Columns["Real"];
            Assert.AreEqual(typeof(Single), c.DotNetType);

            c = v.Columns["SmallDateTime"];
            Assert.AreEqual(typeof(DateTime), c.DotNetType);

            c = v.Columns["SmallInt"];
            Assert.AreEqual(typeof(Int16), c.DotNetType);

            c = v.Columns["SmallMoney"];
            Assert.AreEqual(typeof(Decimal), c.DotNetType);

            c = v.Columns["SqlVariant"];
            Assert.AreEqual(typeof(Object), c.DotNetType);

            c = v.Columns["Text"];
            Assert.AreEqual(typeof(string), c.DotNetType);

            c = v.Columns["Timestamp"];
            Assert.AreEqual(typeof(byte[]), c.DotNetType);

            c = v.Columns["TinyInt"];
            Assert.AreEqual(typeof(byte), c.DotNetType);

            c = v.Columns["UniqueIdentifier"];
            Assert.AreEqual(typeof(Guid), c.DotNetType);

            c = v.Columns["VarBinary"];
            Assert.AreEqual(typeof(byte[]), c.DotNetType);

            c = v.Columns["VarBinaryMax"];
            Assert.AreEqual(typeof(byte[]), c.DotNetType);

            c = v.Columns["VarChar"];
            Assert.AreEqual(typeof(string), c.DotNetType);

            c = v.Columns["VarCharMax"];
            Assert.AreEqual(typeof(string), c.DotNetType);

            c = v.Columns["Xml"];
            Assert.AreEqual(typeof(XmlDocument), c.DotNetType);
        }

        /// <summary>
        /// This is currently not supported for views
        /// </summary>
        [Test]
        public void IsIdentity()
        {
            View v = _database.Views["dbo.v_CourseStudents"];
            ViewColumn c;

            c = v.Columns["CourseID"];
            Assert.IsFalse(c.IsIdentity);

            c = v.Columns["Name"];
            Assert.IsFalse(c.IsIdentity);
        }

        [Test]
        public void IsNullable()
        {
            View v = _database.Views["dbo.v_CourseStudents"];
            ViewColumn c;

            c = v.Columns["CourseID"];
            Assert.IsFalse(c.IsNullable);

            c = v.Columns["FirstName"];
            Assert.IsTrue(c.IsNullable);

            c = v.Columns["LastName"];
            Assert.IsTrue(c.IsNullable);
        }

        [Test]
        public void IsComputed()
        {
            View v = _database.Views["dbo.v_CourseStudents"];
            ViewColumn c;

            c = v.Columns["FirstName"];
            Assert.IsFalse(c.IsComputed);

        }

        [Test]
        public void InForeignKey()
        {
            View v = _database.Views["dbo.v_CourseStudents"];
            ViewColumn c;

            c = v.Columns["CourseID"];
            Assert.IsFalse(c.InForeignKey);

        }

        [Test]
        public void NumericPrecision()
        {
            View v = _database.Views["dbo.v_AllDataTypes"];
            ViewColumn c;

            c = v.Columns["BigInt"];
            Assert.AreEqual(19, c.NumericPrecision);

            c = v.Columns["Binary"];
            Assert.AreEqual(null, c.NumericPrecision);

            c = v.Columns["Bit"];
            Assert.AreEqual(null, c.NumericPrecision);

            c = v.Columns["Char"];
            Assert.AreEqual(null, c.NumericPrecision);

            c = v.Columns["DateTime"];
            Assert.AreEqual(null, c.NumericPrecision);

            c = v.Columns["Decimal"];
            Assert.AreEqual(18, c.NumericPrecision);

            c = v.Columns["Int"];
            Assert.AreEqual(10, c.NumericPrecision);

            c = v.Columns["Money"];
            Assert.AreEqual(19, c.NumericPrecision);

            c = v.Columns["Nchar"];
            Assert.AreEqual(null, c.NumericPrecision);

            c = v.Columns["Ntext"];
            Assert.AreEqual(null, c.NumericPrecision);

            c = v.Columns["Numeric"];
            Assert.AreEqual(18, c.NumericPrecision);

            c = v.Columns["Nvarchar"];
            Assert.AreEqual(null, c.NumericPrecision);

            c = v.Columns["NVarcharMax"];
            Assert.AreEqual(null, c.NumericPrecision);

            c = v.Columns["Real"];
            Assert.AreEqual(24, c.NumericPrecision);

            c = v.Columns["SmallDateTime"];
            Assert.AreEqual(null, c.NumericPrecision);

            c = v.Columns["SmallInt"];
            Assert.AreEqual(5, c.NumericPrecision);

            c = v.Columns["SmallMoney"];
            Assert.AreEqual(10, c.NumericPrecision);

            c = v.Columns["SqlVariant"];
            Assert.AreEqual(null, c.NumericPrecision);

            c = v.Columns["Text"];
            Assert.AreEqual(null, c.NumericPrecision);

            c = v.Columns["Timestamp"];
            Assert.AreEqual(null, c.NumericPrecision);

            c = v.Columns["TinyInt"];
            Assert.AreEqual(3, c.NumericPrecision);

            c = v.Columns["UniqueIdentifier"];
            Assert.AreEqual(null, c.NumericPrecision);

            c = v.Columns["VarBinary"];
            Assert.AreEqual(null, c.NumericPrecision);

            c = v.Columns["VarBinaryMax"];
            Assert.AreEqual(null, c.NumericPrecision);

            c = v.Columns["VarChar"];
            Assert.AreEqual(null, c.NumericPrecision);

            c = v.Columns["VarCharMax"];
            Assert.AreEqual(null, c.NumericPrecision);

            c = v.Columns["Xml"];
            Assert.AreEqual(null, c.NumericPrecision);
        }

        [Test]
        public void NumericScale()
        {
            View v = _database.Views["dbo.v_AllDataTypes"];
            ViewColumn c;

            c = v.Columns["BigInt"];
            Assert.AreEqual(0, c.NumericScale);

            c = v.Columns["Binary"];
            Assert.AreEqual(null, c.NumericScale);

            c = v.Columns["Bit"];
            Assert.AreEqual(null, c.NumericScale);

            c = v.Columns["Char"];
            Assert.AreEqual(null, c.NumericScale);

            c = v.Columns["DateTime"];
            Assert.AreEqual(null, c.NumericScale);

            c = v.Columns["Decimal"];
            Assert.AreEqual(0, c.NumericScale);

            c = v.Columns["Int"];
            Assert.AreEqual(0, c.NumericScale);

            c = v.Columns["Money"];
            Assert.AreEqual(4, c.NumericScale);

            c = v.Columns["Nchar"];
            Assert.AreEqual(null, c.NumericScale);

            c = v.Columns["Ntext"];
            Assert.AreEqual(null, c.NumericScale);

            c = v.Columns["Numeric"];
            Assert.AreEqual(18, c.NumericPrecision);

            c = v.Columns["Nvarchar"];
            Assert.AreEqual(null, c.NumericScale);

            c = v.Columns["NVarcharMax"];
            Assert.AreEqual(null, c.NumericScale);

            c = v.Columns["Real"];
            Assert.AreEqual(null, c.NumericScale);

            c = v.Columns["SmallDateTime"];
            Assert.AreEqual(null, c.NumericScale);

            c = v.Columns["SmallInt"];
            Assert.AreEqual(0, c.NumericScale);

            c = v.Columns["SmallMoney"];
            Assert.AreEqual(4, c.NumericScale);

            c = v.Columns["SqlVariant"];
            Assert.AreEqual(null, c.NumericScale);

            c = v.Columns["Text"];
            Assert.AreEqual(null, c.NumericScale);

            c = v.Columns["Timestamp"];
            Assert.AreEqual(null, c.NumericScale);

            c = v.Columns["TinyInt"];
            Assert.AreEqual(0, c.NumericScale);

            c = v.Columns["UniqueIdentifier"];
            Assert.AreEqual(null, c.NumericScale);

            c = v.Columns["VarBinary"];
            Assert.AreEqual(null, c.NumericScale);

            c = v.Columns["VarBinaryMax"];
            Assert.AreEqual(null, c.NumericScale);

            c = v.Columns["VarChar"];
            Assert.AreEqual(null, c.NumericScale);

            c = v.Columns["VarCharMax"];
            Assert.AreEqual(null, c.NumericScale);

            c = v.Columns["Xml"];
            Assert.AreEqual(null, c.NumericScale);
        }

        [Test]
        public void OrdinalPosition()
        {
            View v = _database.Views["dbo.v_CourseStudents"];
            ViewColumn c;

            c = v.Columns["CourseID"];
            Assert.AreEqual(1, c.OrdinalPosition);

            c = v.Columns["Name"];
            Assert.AreEqual(2, c.OrdinalPosition);

            c = v.Columns["FirstName"];
            Assert.AreEqual(3, c.OrdinalPosition);

            c = v.Columns["LastName"];
            Assert.AreEqual(4, c.OrdinalPosition);
        }

        [Test]
        public void Parent()
        {
            View v = _database.Views["dbo.v_CourseStudents"];
            ViewColumn c;

            c = v.Columns["CourseID"];
            Assert.AreEqual(v.Name, c.Parent.Name);
        }
    }
}
